package com.xhd.file;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;

import com.xhd.base.log.Log;
import com.xhd.base.log.LogFactory;
import com.xhd.base.util.Date;

public class XCompressedFile {
	 private int jm42 = 0;
	  private int[] jm43 = new int[256];
	  private static XCompressedFile jm16 = null;
	  private static final int jm44 = 36;
	  private static final Log jm9;
	  static Class jm10;

	  static
	  {
	    Class tmp7_4 = jm10;
	    if (tmp7_4 == null)
	    {
	 
	      try
	      {
	       XCompressedFile.jm10 = Class.forName("com.sinocc.base.file.XCompressedFile");
	      }
	      catch (ClassNotFoundException localClassNotFoundException)
	      {
	        throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
	      }
	    }
	    jm9 = LogFactory.getLog(tmp7_4);
	  }

	  private XCompressedFile()
	  {
	    jm40();
	  }

	  public static synchronized XCompressedFile getInstance()
	  {
	    if (jm16 == null)
	      jm16 = new XCompressedFile();
	    return jm16;
	  }

	  public boolean extractTo(String paramString1, String paramString2)
	    throws IOException
	  {
	    return decompressFile(paramString1, paramString2);
	  }

	  public int getCRC32(File paramFile)
	    throws IOException
	  {
	    FileInputStream localFileInputStream = null;
	    localFileInputStream = new FileInputStream(paramFile);
	    try
	    {
	      int i = 0;
	      int j = -1;
	      byte[] arrayOfByte = new byte[10239];
	      int k = localFileInputStream.available() - this.jm42;
	      while (k > 0)
	      {
	        if (k >= 10240)
	          i = 10240;
	        else
	          i = k;
	        arrayOfByte = new byte[i];
	       int   l = localFileInputStream.read(arrayOfByte);
	        for (int i1 = 0; i1 < l; ++i1)
	          j = jm41(j, 8) & 0xFFFFFF ^ this.jm43[((j ^ arrayOfByte[i1]) & 0xFF)];
	        k -= i;
	      }
	      localFileInputStream.close();
	      int l = j ^ 0xFFFFFFFF;
	      return l;
	    }
	    catch (IOException localIOException)
	    {
	      try
	      {
	        if (localFileInputStream != null)
	          localFileInputStream.close();
	      }
	      catch (Exception localException)
	      {
	      }
	      throw localIOException;
	    }
	  }

	  public boolean decompressFile(String paramString1, String paramString2)
	  {
	    try
	    {
	      File localFile = new File(paramString1);
	      if ((localFile == null) || (!(localFile.exists())))
	        return false;
	      ArchiveHeader localArchiveHeader = jm35(localFile);
	      if (localArchiveHeader == null)
	        return false;
	      int i = 0;
	      byte[] arrayOfByte = new byte[32768];
	      Object localObject = null;
	      FileOutputStream localFileOutputStream = new FileOutputStream(paramString2);
	      if (localArchiveHeader.jm381)
	      {
	        FileInputStream localFileInputStream = new FileInputStream(localFile);
	        localObject = new InflaterInputStream(localFileInputStream);
	        while (true)
	        {
	          i = ((InputStream)localObject).read(arrayOfByte);
	          if (i < 0)
	         localFileOutputStream.close();
	          if (i <= 0)
	            continue;
	          localFileOutputStream.write(arrayOfByte, 0, i);
	        }
	      }
	      else
	      {
	        localObject = new FileInputStream(localFile);
	        long l = 0L;
	        while (l < localArchiveHeader.jm378)
	        {
	          i = 32768;
	          if (l + i > localArchiveHeader.jm378)
	            i = (int)(localArchiveHeader.jm378 - l);
	          i = ((InputStream)localObject).read(arrayOfByte, 0, i);
	          if (i < 0)
	            break;
	          if (i <= 0)
	            continue;
	          l += i;
	          localFileOutputStream.write(arrayOfByte, 0, i);
	          localFileOutputStream.flush();
	        }
	      }
	      label230: localFileOutputStream.close();
	      ((InputStream)localObject).close();
	      return true;
	    }
	    catch (Exception localException)
	    {
	      jm9.error(localException);
	    }
	    return false;
	  }

	  public int decompressFile(String paramString, OutputStream paramOutputStream)
	  {
	    try
	    {
	      File localFile = new File(paramString);
	      if ((localFile == null) || (!(localFile.exists())))
	        return -1;
	      ArchiveHeader localArchiveHeader = jm35(localFile);
	      if (localArchiveHeader == null)
	        return -2;
	      int i = 0;
	      int j = 0;
	      byte[] arrayOfByte = new byte[32768];
	      Object localObject = null;
	      if (localArchiveHeader.jm381)
	      {
	        FileInputStream localFileInputStream = new FileInputStream(localFile);
	        localObject = new InflaterInputStream(localFileInputStream);
	        while (true)
	        {
	          i = ((InputStream)localObject).read(arrayOfByte);
	          if (i < 0)
	        	  ((InputStream)localObject).close();
	          if (i <= 0)
	            continue;
	          j += i;
	          paramOutputStream.write(arrayOfByte, 0, i);
	          paramOutputStream.flush();
	        }
	      }
	      else
	      {
	        localObject = new FileInputStream(localFile);
	        long l = 0L;
	        while (l < localArchiveHeader.jm378)
	        {
	          i = 32768;
	          if (l + i > localArchiveHeader.jm378)
	            i = (int)(localArchiveHeader.jm378 - l);
	          i = ((InputStream)localObject).read(arrayOfByte, 0, i);
	          if (i < 0)
	            break;
	          if (i <= 0)
	            continue;
	          j += i;
	          l += i;
	          paramOutputStream.write(arrayOfByte, 0, i);
	          paramOutputStream.flush();
	        }
	      }
	      label239: ((InputStream)localObject).close();
	      return j;
	    }
	    catch (Exception localException)
	    {
	      jm9.error(localException);
	    }
	    return -3;
	  }

	  public boolean compressFile(String paramString1, String paramString2)
	  {
	    try
	    {
	      File localFile1 = new File(paramString1);
	      if ((!(localFile1.exists())) || (localFile1.length() < 1L))
	        return false;
	      File localFile2 = new File(paramString2);
	      FileInputStream localFileInputStream = new FileInputStream(localFile1);
	      FileOutputStream localFileOutputStream = new FileOutputStream(localFile2);
	      DeflaterOutputStream localDeflaterOutputStream = new DeflaterOutputStream(localFileOutputStream);
	      int i = getCRC32(localFile1);
	      int j = 0;
	      byte[] arrayOfByte = new byte[32768];
	      int k = 0;
	      while (true)
	      {
	        j = localFileInputStream.read(arrayOfByte);
	        if (j < 0)
	          break;
	        if (j <= 0)
	          continue;
	        k += j;
	        localDeflaterOutputStream.write(arrayOfByte, 0, j);
	        localDeflaterOutputStream.flush();
	      }
	      localDeflaterOutputStream.close();
	      localFileOutputStream.close();
	      localFileInputStream.close();
	      return jm36(localFile2, localFile1.getName(), new Date(localFile1.lastModified()), i, k);
	    }
	    catch (Exception localException)
	    {
	      jm9.error(localException);
	    }
	    return false;
	  }

	  private byte[] jm33(byte[] paramArrayOfByte)
	  {
	    try
	    {
	      ByteArrayInputStream localByteArrayInputStream = new ByteArrayInputStream(paramArrayOfByte);
	      ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();
	      DeflaterOutputStream localDeflaterOutputStream = new DeflaterOutputStream(localByteArrayOutputStream);
	      int i = 0;
	      byte[] arrayOfByte = new byte[1024];
	      while (true)
	      {
	        i = localByteArrayInputStream.read(arrayOfByte);
	        if (i < 0)
	          break;
	        if (i <= 0)
	          continue;
	        localDeflaterOutputStream.write(arrayOfByte, 0, i);
	      }
	      localDeflaterOutputStream.close();
	      localByteArrayOutputStream.close();
	      localByteArrayInputStream.close();
	      return localByteArrayOutputStream.toByteArray();
	    }
	    catch (Exception localException)
	    {
	      jm9.error(localException);
	    }
	    return null;
	  }

	  private byte[] jm34(byte[] paramArrayOfByte)
	  {
	    try
	    {
	      int i = 0;
	      byte[] arrayOfByte = new byte[1024];
	      ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();
	      InflaterInputStream localInflaterInputStream = new InflaterInputStream(new ByteArrayInputStream(paramArrayOfByte));
	      while (true)
	      {
	        i = localInflaterInputStream.read(arrayOfByte);
	        if (i < 0)
	          break;
	        if (i <= 0)
	          continue;
	        localByteArrayOutputStream.write(arrayOfByte, 0, i);
	      }
	      localByteArrayOutputStream.close();
	      localInflaterInputStream.close();
	      return localByteArrayOutputStream.toByteArray();
	    }
	    catch (Exception localException)
	    {
	      jm9.error(localException);
	    }
	    return null;
	  }

	  private ArchiveHeader jm35(File paramFile)
	    throws IOException
	  {
	    RandomAccessFile localRandomAccessFile = new RandomAccessFile(paramFile, "r");
	    byte[] arrayOfByte = new byte[1024];
	    try
	    {
	      long l = localRandomAccessFile.length();
	      localRandomAccessFile.seek(l - 36L);
	      if (36 != localRandomAccessFile.read(arrayOfByte));
	      ArchiveHeader localArchiveHeader1;
	      do
	      {
	       
	        localArchiveHeader1 = new ArchiveHeader();
	        localArchiveHeader1.fromBytes(arrayOfByte);
	        localRandomAccessFile.seek(l - localArchiveHeader1.jm377 - 36L);
	      }
	      while (localArchiveHeader1.jm377 != localRandomAccessFile.read(arrayOfByte, 0, localArchiveHeader1.jm377));
	      if (localArchiveHeader1.jm379)
	        arrayOfByte = jm34(arrayOfByte);
	      localArchiveHeader1.jm381 = (1 != arrayOfByte[784]);
	      ArchiveHeader localArchiveHeader2 = localArchiveHeader1;
	      return localArchiveHeader2;
	    }
	    finally
	    {
	      try
	      {
	        localRandomAccessFile.close();
	      }
	      catch (Exception localException)
	      {
	      }
	    }
	  }

	  private boolean jm36(File paramFile, String paramString, Date paramDate, int paramInt1, int paramInt2)
	  {
	    try
	    {
	      byte[] arrayOfByte = (byte[])null;
	      int i = (int)paramFile.length();
	      SimpleDateFormat localSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	      String str = localSimpleDateFormat.format(paramDate);
	      ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();
	      localByteArrayOutputStream.write(jm39(paramString));
	      localByteArrayOutputStream.write(jm39(null));
	      localByteArrayOutputStream.write(jm39(str));
	      localByteArrayOutputStream.write(jm37(paramInt2));
	      localByteArrayOutputStream.write(jm37(i));
	      localByteArrayOutputStream.write(jm37(0));
	      localByteArrayOutputStream.write(jm37(paramInt1));
	      localByteArrayOutputStream.write(jm38(2));
	      localByteArrayOutputStream.write(jm38(0));
	      localByteArrayOutputStream.close();
	      arrayOfByte = localByteArrayOutputStream.toByteArray();
	      arrayOfByte = jm33(arrayOfByte);
	      int j = arrayOfByte.length;
	      FileOutputStream localFileOutputStream = new FileOutputStream(paramFile, true);
	      localFileOutputStream.write(arrayOfByte);
	      localFileOutputStream.close();
	      localByteArrayOutputStream.reset();
	      localByteArrayOutputStream.write(jm37(getCRC32(paramFile)));
	      localByteArrayOutputStream.write(jm37(1));
	      localByteArrayOutputStream.write(jm37(1));
	      localByteArrayOutputStream.write(jm37(j));
	      localByteArrayOutputStream.write(jm37(i));
	      localByteArrayOutputStream.write(jm37(1));
	      arrayOfByte = new byte[12];
	      localByteArrayOutputStream.write(arrayOfByte);
	      arrayOfByte = localByteArrayOutputStream.toByteArray();
	      localFileOutputStream = new FileOutputStream(paramFile, true);
	      localFileOutputStream.write(arrayOfByte);
	      localFileOutputStream.close();
	    }
	    catch (Exception localException)
	    {
	      jm9.error(localException);
	      return false;
	    }
	    return true;
	  }

	  private byte[] jm37(int paramInt)
	  {
	    byte[] arrayOfByte = new byte[4];
	    arrayOfByte[3] = (byte)(paramInt >>> 24);
	    arrayOfByte[2] = (byte)(paramInt >>> 16);
	    arrayOfByte[1] = (byte)(paramInt >>> 8);
	    arrayOfByte[0] = (byte)(paramInt >>> 0);
	    return arrayOfByte;
	  }

	  private byte[] jm38(int paramInt)
	  {
	    byte[] arrayOfByte = new byte[2];
	    arrayOfByte[0] = (byte)(paramInt >>> 8);
	    arrayOfByte[1] = (byte)(paramInt >>> 0);
	    return arrayOfByte;
	  }

	  private byte[] jm39(String paramString)
	  {
	    byte[] arrayOfByte1 = new byte[256];
	    int i = 0;
	    if ((paramString != null) && (paramString.length() > 0))
	    {
	      byte[] arrayOfByte2 = paramString.getBytes();
	      i = (byte)arrayOfByte2.length;
	      arrayOfByte1[0] = (byte)i;
	      System.arraycopy(arrayOfByte2, 0, arrayOfByte1, 1, arrayOfByte2.length);
	    }
	    else
	    {
	      arrayOfByte1[0] = 0;
	    }
	    for (int j = i + 1; j < 256; ++j)
	      arrayOfByte1[j] = 0;
	    return arrayOfByte1;
	  }

	  private void jm40()
	  {
	    int j = -306674912;
	    for (int k = 0; k <= 255; ++k)
	    {
	      int i = k;
	      for (int l = 8; l >= 1; --l)
	        if ((i & 0x1) == 1)
	          i = jm41(i, 1) ^ j;
	        else
	          i = jm41(i, 1);
	      this.jm43[k] = i;
	    }
	  }

	  private int jm41(int paramInt1, int paramInt2)
	  {
	    int i = paramInt1 >> paramInt2;
	    if (paramInt1 < 0)
	    {
	      int j = 2147483647;
	      i &= j;
	    }
	    return i;
	  }

	  public static void main(String[] paramArrayOfString)
	  {
	    try
	    {
	      String str1 = "C:\\temp\\test.txt";
	      String str2 = "C:\\temp\\test.cpc";
	      String str3 = "C:\\temp\\test.txt.tmp";
	      XCompressedFile localXCompressedFile = getInstance();
	      if (!(localXCompressedFile.compressFile(str1, str2)))
	      {
	        System.out.println("compressFile error!");
	        return;
	      }
	      System.out.println("compressFile ok");
	      if (!(localXCompressedFile.decompressFile(str2, str3)))
	      {
	        System.out.println("decompressFile error!");
	        return;
	      }
	      System.out.println("decompressFile ok");
	      if (localXCompressedFile.getCRC32(new File(str1)) != localXCompressedFile.getCRC32(new File(str3)))
	      {
	        System.out.println("CRC error");
	        return;
	      }
	      System.out.println("CRC OK");
	    }
	    catch (Exception localException)
	    {
	      localException.printStackTrace();
	    }
	  }

	  class ArchiveHeader
	  {
	    int jm374 = 0;
	    int jm375 = 0;
	    int jm376 = 1;
	    int jm377 = 0;
	    long jm378 = 0L;
	    boolean jm379 = true;
	    byte[] jm380 = new byte[12];
	    boolean jm381 = true;

	    public boolean fromBytes(byte[] paramArrayOfByte)
	    {
	      int i = 0;
	      this.jm374 = jm373(paramArrayOfByte, i);
	      this.jm375 = jm373(paramArrayOfByte, i += 4);
	      this.jm376 = jm373(paramArrayOfByte, i += 4);
	      this.jm377 = jm373(paramArrayOfByte, i += 4);
	      this.jm378 = jm373(paramArrayOfByte, i += 4);
	      this.jm379 = (1 == jm373(paramArrayOfByte, i += 4));
	      return true;
	    }

	    private int jm373(byte[] paramArrayOfByte, int paramInt)
	    {
	      int i = 0;
	      i |= 0xFF & paramArrayOfByte[paramInt];
	      i |= 0xFF & paramArrayOfByte[(paramInt + 1)] << 8;
	      i |= 0xFF & paramArrayOfByte[(paramInt + 2)] << 16;
	      i |= 0xFF & paramArrayOfByte[(paramInt + 3)] << 24;
	      return i;
	    }

	    public String toString()
	    {
	      StringBuffer localStringBuffer = new StringBuffer(256);
	      localStringBuffer.append("CRC=" + this.jm374);
	      localStringBuffer.append(",FileCount=" + this.jm375);
	      localStringBuffer.append(",Version=" + this.jm376);
	      localStringBuffer.append(",RegistrySize=" + this.jm377);
	      localStringBuffer.append(",ArchiveSize=" + this.jm378);
	      localStringBuffer.append(",CompressedRegistry=" + this.jm379);
	      localStringBuffer.append(",CompressedData=" + this.jm381);
	      return localStringBuffer.toString();
	    }
	  }
}
